using System;
using Infinity.Common;

namespace Infinity.API.Core
{
	public class LoopCodeAction : CodeAction
	{
		public Func<bool> Condition { get; protected set; }
		public CodeAction Action { get; protected set; }

		public LoopCodeAction(Func<bool> condition, CodeAction action)
		{
			Condition = Ensure.NotNull(condition);
			Action = Ensure.NotNull(action);
		}

		/// <summary>
		/// Run action
		/// </summary>
		public override void Run()
		{
			OnExecuting(this);

			while (EvaluteCondition())
				Action.Run();

			OnExecuted(this);
		}

		public event Action<LoopCodeAction> ConditionExecuting;

		public void OnConditionExecuting(LoopCodeAction obj)
		{
			Action<LoopCodeAction> handler = ConditionExecuting;
			if (handler != null) handler(obj);
		}

		public event Action<LoopCodeAction> ConditionExecuted;

		public void OnConditionExecuted(LoopCodeAction obj)
		{
			Action<LoopCodeAction> handler = ConditionExecuted;
			if (handler != null) handler(obj);
		}

		private bool EvaluteCondition()
		{
			OnConditionExecuting(this);
			var result = Condition();
			OnConditionExecuted(this);

			return result;
		}
	}
}